package org.example.quartz.BIP;

import cn.hutool.core.date.StopWatch;
import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.SqlService;
import org.example.quartz.service.UtilService;
import org.example.quartz.task.QuartzTaskJob;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class CustomerListQuartz_BIP implements QuartzTaskJob {

    Map<String, Object> gsMap = DataSourceUtil.getGS();
    //全局接口配置
    String IP = (String) gsMap.get("IP");
    String PORT = (String) gsMap.get("PORT");
    String ECC = (String) gsMap.get("ECC");
    String Bearer = (String) gsMap.get("Bearer");

    //日志
    LogService loginfo = SpringUtil.getBean(LogService.class);
    //orgService
    OrgService orgService = SpringUtil.getBean(OrgService.class);
    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);

    SqlService sqlService = SpringUtil.getBean(SqlService.class);

    /**
     * 往来单位接口（供应商、客户）
     * 接口地址：GSCloud文档3.15
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncWldwList
     **/
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        try {
            //传入变量 lastTime 最后抓取时间
            //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
            //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
            //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
            //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
            //查询脚本
            /**
             *
             bd_custaddress  地址
             bd_custbank        银行
             * */
            String methodName = "CustomerListQuartz";
            JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
            //1、查询时间
            String ts = utilService.getTs(methodName, jdbcTemplate);
            //2、根据时间查询数据集 (停用和删除的过滤掉，暂不考虑，线下处理)
            String selectSQL = sqlService.getCustomerSelectSql(ts);
            //查询数据，根据数据结果推送给GS浪潮
            Session oracleSession = DataSourceUtil.getLSOracleSession();
            List<Entity> query0 = oracleSession.query(selectSQL);
            System.out.println(query0.size());
            //拼装数据，推送给浪潮
            if (query0.size() > 0) {
                String yyid = "";
                String TS = "";
                //每批推送20个
                List<List<Entity>> queryList = this.splitLsit(query0, 20);
                for (List<Entity> query : queryList) {
                    String GsJson = "[";
                    //根据公司、账套进行拆分推送，根据组织编码，查询出账套信息，如果有多个账套，轮询进行处理
                    List<Map<String, Object>> yyztCodeMap = orgService.selectCusZtCode(jdbcTemplate);
                    for (Map<String, Object> gSmap : query) {
                        //更换gsCode
                        // String gsCode = orgService.selectGsCode((String) gSmap.get("ORGCODE"), jdbcTemplate);
                        //客商PK主键(同客户主键、供应商主键)
                        String PK_CUST_SUP = (String) gSmap.get("ID");
                        TS = (String) gSmap.get("TS");
                        yyid += (String) gSmap.get("ID") + ",";
                        //查询地址信息  bd_custaddress\bd_supaddress
                        //关联查询客户地址+供应商地址
                        String addressSQL = sqlService.getAddressSQL(PK_CUST_SUP);
                        // List<Entity> addressMap = oracleSession.query(addressSQL);
                        //查询银行信息  bd_custbank
                        String bankaccountSQL = sqlService.getBankaccountSQL(PK_CUST_SUP);
                        // List<Entity> bankMap = oracleSession.query(bankaccountSQL);
                        //查询联系人信息
                        String contactSQL = sqlService.getContactSQL(PK_CUST_SUP);
                        //List<Entity> contactMap = oracleSession.query(contactSQL);

                        //账簿轮询
                        for (int x = 0; x < yyztCodeMap.size(); x++) {
                            String yyztCode = (String) yyztCodeMap.get(x).get("yyztCode");
                            String orgCode = (String) yyztCodeMap.get(x).get("gsCode");
                            GsJson +=
                                    "{\n" +
                                            "\"CODE\":\"" + gSmap.get("CODE").toString().replace("$", orgCode) + "\",\n" +
                                            "\"NAME\":\"" + gSmap.get("CODE").toString().replace("$", orgCode) + gSmap.get("Name") + orgCode + "\",\n" +
                                            //"\"TYPECODE\":\"" + gSmap.get("TYPECODE") + "\",\n" +
                                            //"\"TYPENAME\":\"" + gSmap.get("TYPENAME") + "\",\n" +
                                            "\"AREACODE\":\"" + gSmap.get("AREACODE") + "\",\n" +
                                            "\"AREANAME\":\"" + gSmap.get("AREANAME") + "\",\n" +
                                            //"\"DOMAINTYPE\":\"" + gSmap.get("DOMAINTYPE") + "\",\n" +
                                            "\"ORGCODE\":\"" + orgCode + "\",\n" +
                                            "\"DEFAULTCURRENCY\":\"" + gSmap.get("DEFAULTCURRENCY") + "\",\n" +
                                            "\"ORGANIZATIONCODE\":\"" + gSmap.get("ORGANIZATIONCODE") + "\",\n" +
                                            "\"EXTC_YCODE\":\"" + gSmap.get("EXTC_YCODE") + "\",\n" +
                                            "\"EXTC_YNAME\":\"" + gSmap.get("EXTC_YNAME") + "\",\n" +
                                            "\"UNITNATURECODE\":\"\",\n" +
                                            "\"UNITNATURENAME\":\"\",\n" +
                                            "\"EXTC_TYPECODE\":\"\",\n" +
                                            "\"EXTC_TYPENAME\":\"\",\n" +
                                            "\"ADDRESS\":[\n";
                            //拼装地址信息
//                        if (addressMap.size() > 0) {
//                            for (Map<String, Object> addressObj : addressMap) {
//                                GsJson +=
//                                        "{\n" +
//                                                "\"CODE\":\"" + addressObj.get("CODE") + "\",\n" +
//                                                "\"COUNTRYORREGION\":\"" + addressObj.get("COUNTRYORREGION") + "\",\n" +
//                                                "\"ADDRTYPE\":\"" + addressObj.get("ADDRTYPE") + "\",\n" +
//                                                "\"ISMAIN\":\"" + addressObj.get("ISMAIN") + "\",\n" +
//                                                "\"STREETNO\":\"" + addressObj.get("STREETNO") + "\",\n" +
//                                                "\"CONTACTNUM\":\"" + addressObj.get("CONTACTNUM") + "\",\n" +
//                                                "\"REMARK\":\"" + addressObj.get("REMARK") + "\"\n" +
//                                                "     },";
//                            }
//                            //去掉拼接的最后一个字符
//                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
//                        }
                            GsJson += "],\n" +
                                    " \"CONTACT\":[\n";
//                        if (contactMap.size() > 0) {
////                            for (Map<String, Object> contactObj : contactMap) {
////                                GsJson += "{\n" +
////                                        "\"NAME\":\"" + contactObj.get("NAME") + "\",\n" +
////                                        "\"IDENTITYTYPE\":\"" + contactObj.get("IDENTITYTYPE") + "\",\n" +
////                                        "\"IDENTITYNUMBER\":\"" + contactObj.get("IDENTITYNUMBER") + "\",\n" +
////                                        "\"GENDER\":\"" + contactObj.get("GENDER") + "\",\n" +
////                                        "\"DUTY\":\"" + contactObj.get("DUTY") + "\",\n" +
////                                        "\"TEL\":\"" + contactObj.get("TEL") + "\",\n" +
////                                        "\"ISMAIN\":\"" + contactObj.get("ISMAIN") + "\",\n" +
////                                        "\"REMARK\":\"" + contactObj.get("REMARK") + "\"\n" +
////                                        " },";
////                            }
////                            //去掉拼接的最后一个字符
////                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
//                        }
                            GsJson += "],\n" +
                                    "\"BANKACCOUNTS\":[\n";
//                        if (bankMap.size() > 0) {
//                            for (Map<String, Object> bankObj : bankMap) {
//                                    GsJson += "{\n" +
//                                            "\"ACCOUNTCODE\":\"" + bankObj.get("ACCOUNTCODE") + "\",\n" +
//                                            "\"ACCOUNTNAME\":\"" + bankObj.get("ACCOUNTNAME") + "\",\n" +
//                                            "\"INBANK\":\"" + bankObj.get("INBANK") + "\",\n" +
//                                            "\"ACCOUNTSTATE\":\"" + bankObj.get("ACCOUNTSTATE") + "\",\n" +
//                                            "\"PRIVATEORPUBLIC\":\"" + bankObj.get("PRIVATEORPUBLIC") + "\",\n" +
//                                            "\"CURRENCYLIST\":\"" + bankObj.get("CURRENCYLIST") + "\",\n" +
//                                            "\"ISMAIN\":\"" + bankObj.get("ISMAIN") + "\",\n" +
//                                            "\"COUNTRY\":\"" + bankObj.get("COUNTRY") + "\",\n" +
//                                            "\"PROVINCE\":\"" + bankObj.get("PROVINCE") + "\",\n" +
//                                            "\"CITY\":\"" + bankObj.get("CITY") + "\",\n" +
//                                            "\"REMARK\":\"" + bankObj.get("REMARK") + "\"\n" +
//                                            "     },";
//
//                            }
//                            //去掉拼接的最后一个字符
//                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
//                        }
                            GsJson += "]\n" + "},";
//

                        }

                    }


                    GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
                    GsJson += "]\n";
                    GsJson = GsJson.replace("null", "");
                    //调用GS接口，推送给GS浪潮，获取返回值;
                    //1、推送用户档案
                    StopWatch st = new StopWatch();
                    System.out.println(methodName + "开始时间：" + LocalDateTime.now());
                    st.start();
                    String gsUrl = IP + ":" + PORT + "/api/jg/syncbddata/v1.0/bdsyncinterface/syncWldwList";
                    String returnMSG = HttpRequest.post(gsUrl)
                            .header("Content-Type", "application/json")
                            .header("Accept-Language", "zh-CHS")
                            .header("X-ECC-Current-Tenant", ECC)
                            .header("Authorization", Bearer).timeout(200000)
                            .body(GsJson).execute().body();
                    st.stop();
                    System.out.println(methodName + "结束时间：" + LocalDateTime.now());
                    System.out.println(methodName + "接口耗时：" + st.getTotalTimeMillis() + "ms");
                    System.out.println(methodName + "接口返回值：" + returnMSG);
                    if (!returnMSG.isEmpty()) {
                        String logInsert = "";
                        JSONObject returnObj = JSONObject.parseObject(returnMSG);
                        //成功
                        if (returnObj.get("code").equals("0")) {
                            //写入日志表
                            int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "成功", GsJson, returnMSG, "", "", gsUrl, TS);
                            if (loginsert > 0) {
                                //System.out.println("日志写入成功！！");
                            } else {
                                System.out.println("日志写入失败！！");
                            }
                            //失败
                        } else if (returnObj.get("code").equals("1")) {
                            //写入日志表
                            int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "失败", GsJson, returnMSG, "", "", gsUrl, TS);
                            if (loginsert > 0) {
                                //System.out.println("日志写入成功！！");
                            } else {
                                System.out.println("日志写入失败！！");
                            }
                        } else if (returnObj.get("code") == null && ("").equals(returnObj.get("code"))) {
                            //写入日志表
                            int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", "", gsUrl, TS);
                            if (loginsert > 0) {
                                //System.out.println("日志写入成功！！");
                            } else {
                                System.out.println("日志写入失败！！");
                            }
                        } else  {
                            //写入日志表
                            int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", "", gsUrl, TS);
                            if (loginsert > 0) {
                                //System.out.println("日志写入成功！！");
                            } else {
                                System.out.println("日志写入失败！！");
                            }
                        }
                    }
                }
            } else {
                System.out.println(methodName + "暂无新数据推送");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //关闭链接
            DataSourceUtil.closeOracleSession();
            DataSourceUtil.closeMysqlSession();
        }
    }

    //根据固定长度，拆分成List
    public List<List<Entity>> splitLsit(List<Entity> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<Entity>> result = new ArrayList<>();

        int size = list.size();
        int count = (size + len - 1) / len;

        for (int i = 0; i < count; i++) {
            List<Entity> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }
}
